package com.huamao.zh.service.impl;

import java.math.BigDecimal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huamao.zh.constants.CashFreezeType;
import com.huamao.zh.constants.CashType;
import com.huamao.zh.constants.RemarkType;
import com.huamao.zh.constants.ScoreFreezeType;
import com.huamao.zh.constants.ScoreSpecialType;
import com.huamao.zh.constants.ScoreFreezeType;
import com.huamao.zh.constants.ScoreType;
import com.huamao.zh.model.Account;
import com.huamao.zh.service.AccountService;
import com.huamao.zh.service.FenrunService;
import com.huamao.zh.service.LogCashFreezeService;
import com.huamao.zh.service.LogCashService;
import com.huamao.zh.service.LogErrorService;
import com.huamao.zh.service.LogMnsService;
import com.huamao.zh.service.LogScoreFreezeService;
import com.huamao.zh.service.LogScoreService;
import com.huamao.zh.service.LogScoreSpecialService;
import com.huamao.zh.service.SysConfigsService;
import com.huamao.zh.service.UsersService;

/**
 * 分润奖励业务执行 Created by Bourne on 2017-11-22.
 */
@Service
@Transactional
public class FenrunServiceImpl implements FenrunService {
	@Autowired
	private UsersService usersService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private LogScoreService logScoreService;
	@Autowired
	private LogScoreFreezeService logScoreFreezeService;
	@Autowired
	private LogScoreSpecialService logScoreSpecialService;
	@Autowired
	private LogCashService logCashService;
	@Autowired
	private LogCashFreezeService logCashFreezeService;
	@Autowired
	private LogErrorService logErrorService;
	@Autowired
	private LogMnsService logMnsService;
	@Autowired
	private SysConfigsService sysConfigsService;

	private String source;
	// A:线下消费金额，B:线上消费金额，C:应得现金奖励，D:购买牌匾金额
	private BigDecimal totalMoney;
	// 消费者本人应得积分
	private BigDecimal totalScore;
	// 特别奖励百分比%
	private String specialProfitRatio;

	public boolean doFenRun(String messageBody) throws Exception {
		JSONObject jsonMsg = (JSONObject) JSON.parse(messageBody);
		Integer userId = jsonMsg.getIntValue("userId");
		Integer shopUserId = jsonMsg.getIntValue("shopUserId");
		source = jsonMsg.getString("source");
		String orderNo = jsonMsg.getString("orderNo");
		totalMoney = new BigDecimal(jsonMsg.getDouble("totalMoney"));
		totalScore = new BigDecimal(jsonMsg.getDouble("totalScore"));

		try {
			// 重复单号不会执行
			logMnsService.add(source, orderNo, userId, messageBody, "");
		} catch (Exception e) {
			e.printStackTrace();
			try {
				logErrorService.add("doFenRunInit", userId, messageBody, e.toString());
			} catch (Exception e1) {

			}
			return true;
		}
		specialProfitRatio = sysConfigsService.getByFieldCode("specialProfit").getFieldValue();
		// 交易方积分业务类型定义
		int type = 1;
		// 邀请方奖励积分业务类型定义
		int inviteType = 1;
		String typeRemark = "";
		String inviteTypeRemark = "";
		switch (source) {
		case "A":
			type = ScoreType.Offline_consumption.getCode();
			typeRemark = ScoreType.Offline_consumption.getName();
			inviteType = ScoreType.Subordinate_consumption.getCode();
			inviteTypeRemark = ScoreType.Subordinate_consumption.getName();
			break;
		case "B":
			type = ScoreType.Online_consumption.getCode();
			typeRemark = ScoreType.Online_consumption.getName();
			inviteType = ScoreType.Subordinate_consumption.getCode();
			inviteTypeRemark = ScoreType.Subordinate_consumption.getName();
			break;
		case "C":
			type = ScoreType.User_upgrade.getCode();
			typeRemark = ScoreType.User_upgrade.getName();
			inviteType = ScoreType.Subordinate_upgrade.getCode();
			inviteTypeRemark = ScoreType.Subordinate_upgrade.getName();
			break;
		case "D":
			type = ScoreType.Paiian_add.getCode();
			typeRemark = ScoreType.Paiian_add.getName();
			inviteType = ScoreType.Paiian_invite_add.getCode();
			inviteTypeRemark = ScoreType.Paiian_invite_add.getName();
			break;
		default:
			break;
		}
		// 消费者本人的积分奖励
		// inviteId1 第一级上级
		Integer inviteId1 = this.addScore(type, 0, userId, totalScore, orderNo, typeRemark);

		// 直接上级邀请人奖励
		// 如果没有直接上级，消费奖励和特别奖励都没有
		if (inviteId1 > 0) {
			if ("A".equals(source) || "B".equals(source) || "D".equals(source)) {
				// 消费分享人奖励比例%
				String fieldValue = sysConfigsService.getByFieldCode("consumeProfit").getFieldValue();
				BigDecimal totalScore1 = totalScore.multiply(new BigDecimal(fieldValue)).divide(new BigDecimal(100));
				// inviteId2 第二级上级，如果存在送特别奖励
				Integer inviteId2 = this.addScore(inviteType, userId, inviteId1, totalScore1, orderNo,
						inviteTypeRemark);
				if (inviteId2 > 0) {
					this.addSpecialReward(inviteId1, inviteId2, totalScore1, 1, orderNo,
							RemarkType.CODE_1001.getName());
				}
			}
			if ("C".equals(source)) {
				String upgradeProfitFlag = sysConfigsService.getByFieldCode("upgradeProfitFlag").getFieldValue();
				if (Integer.parseInt(upgradeProfitFlag) == 1) {
					// 消费分享人奖励比例%
					String fieldValue = sysConfigsService.getByFieldCode("consumeProfit").getFieldValue();
					BigDecimal totalScore1 = totalScore.multiply(new BigDecimal(fieldValue))
							.divide(new BigDecimal(100));
					// inviteId2 第二级上级，如果存在送特别奖励
					Integer inviteId2 = this.addScore(inviteType, userId, inviteId1, totalScore1, orderNo,
							inviteTypeRemark);
					if (inviteId2 > 0) {
						this.addSpecialReward(inviteId1, inviteId2, totalScore1, 1, orderNo,
								RemarkType.CODE_1001.getName());
					}
				}
			}
		}

		// 未归为一类业务
		switch (source) {
		case "A":
		case "B":
			// 商家用户的直接上级进行销售奖励
			// 店铺营业额分享人奖励比例%
			String fieldValue = sysConfigsService.getByFieldCode("turnoverProfit").getFieldValue();
			BigDecimal shopScore1 = totalScore.multiply(new BigDecimal(fieldValue)).divide(new BigDecimal(100));
			Integer inviteShopId1 = usersService.getUserInviteId(shopUserId);
			if (inviteShopId1 != null && inviteShopId1 > 0) {
				Integer inviteShopId2 = this.addScore(ScoreType.Subordinate_turnover.getCode(), shopUserId,
						inviteShopId1, shopScore1, orderNo, RemarkType.CODE_1004.getName());
				if (inviteShopId2 > 0) {
					this.addSpecialReward(inviteShopId1, inviteShopId2, shopScore1, 1, orderNo,
							RemarkType.CODE_1002.getName());
				}
			}
			break;
		case "C":
			// 上级奖励现金
			BigDecimal rewardCash = totalMoney;
			if (rewardCash.compareTo(BigDecimal.valueOf(0)) == 0) {
				return true;
			}
			this.addCash(userId, inviteId1, rewardCash, orderNo, RemarkType.CODE_1003.getName());
			break;
		case "D":
			// 无
			break;
		default:
			break;
		}
		return true;
	}

	/**
	 * Desc:计算消费奖励 Author: Bourne Date: 2017-11-22 11:03
	 *
	 * @param type
	 *            业务type
	 * @param fromId
	 *            奖励来源用户userId
	 * @param userId
	 *            奖励用户userId
	 * @param addScore
	 *            奖励积分
	 * @param orderNo
	 *            业务单号
	 * @param remark
	 *            业务备注
	 * @return
	 */
	private Integer addScore(int type, Integer fromId, Integer userId, BigDecimal addScore, String orderNo,
			String remark) {
		try {
			Account userAccount = usersService.getUserAccount(userId);
			if (userAccount == null) {
				return -1;
			}
			Account account = new Account();// 准备更新的账户表记录
			Integer accountId = userAccount.getAccountId();
			account.setAccountId(accountId);
			if (userAccount.getUsers().getUserType() > 0 || fromId == 0) {
				account.setScore(addScore);
				account.setTotalScore(addScore);
				if ("A".equals(source)) {
					account.setOfflineExpenditure(totalMoney);
				}
				logScoreService.add(type, fromId, userId, orderNo, userAccount.getScore(), 1, addScore, remark);
			} else {
				account.setFreezeScore(addScore);
				logScoreFreezeService.add(type, fromId, userId, orderNo, userAccount.getFreezeScore(), 1, addScore,
						remark);
			}

			accountService.addFenrun(account);
			return userAccount.getUsers().getInviteId();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				logErrorService.add("doFenrunAddScore", 0, "orderNo:" + orderNo + ",fromId:" + fromId + ",userId:"
						+ userId + ",addScore:" + addScore + ",remark:" + remark, e.toString());
			} catch (Exception e1) {

			}
			return -1;
		}
	}

	/**
	 * Desc:用户升级现金奖励 Author: Bourne Date: 2017-11-22 17:35
	 *
	 * @param fromId
	 *            推荐用户id
	 * @param cashUserId
	 *            被奖励用户id
	 * @param addCash
	 *            奖励现金
	 * @param orderNo
	 *            订单号
	 * @param remark
	 *            备注
	 * @return
	 */
	private Integer addCash(Integer fromId, Integer cashUserId, BigDecimal addCash, String orderNo, String remark) {
		try {
			Account userAccount = usersService.getUserAccount(cashUserId);
			if (userAccount == null) {
				return -1;
			}
			Account account = new Account();
			Integer accountId = userAccount.getAccountId();
			account.setAccountId(accountId);
			if (userAccount.getUsers().getUserType() == 0) {
				account.setFreezeCash(addCash);
				logCashFreezeService.sumCashFreeze(CashFreezeType.Xiaxian_shengji, fromId, cashUserId, orderNo,
						userAccount.getFreezeCash(), addCash, remark);
			} else {
				account.setCash(addCash);
				account.setTotalCash(addCash);
				logCashService.sumCash(CashType.Xiaxian_shengji, fromId, cashUserId, orderNo, userAccount.getCash(),
						addCash, remark);
			}
			accountService.addFenrun(account);
			return userAccount.getUsers().getInviteId();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				logErrorService.add("doFenrunAddSCash", 0,
						"orderNo:" + orderNo + ",fromId:" + fromId + ",userId:" + cashUserId + ",addCash:" + addCash,
						e.toString());
			} catch (Exception e1) {

			}
			return -1;
		}
	}

	/**
	 * Desc: 计算特别奖励 Author: Bourne Date: 2017-11-22 11:03
	 *
	 * @param specialFromId
	 *            特别奖励userId的上级
	 * @param specialUserId
	 *            特别奖励userId的
	 * @param totalSpecialReward
	 *            fromId得到积分总数
	 * @param num
	 *            奖励次序
	 * @param orderNo
	 *            业务单号
	 * @param remark
	 *            备注
	 * @return
	 */
	private boolean addSpecialReward(Integer specialFromId, Integer specialUserId, BigDecimal totalSpecialReward,
			int num, String orderNo, String remark) {
		try {
			if (specialUserId == 0) {
				return true;
			}
			// 被奖励人是上级应得的50%
			totalSpecialReward = totalSpecialReward.multiply(new BigDecimal(specialProfitRatio))
					.divide(new BigDecimal(100));
			// 1份特别奖励的积分数
			BigDecimal oneSpecialReward = totalSpecialReward.multiply(BigDecimal.valueOf(0.2));
			if (oneSpecialReward.compareTo(BigDecimal.valueOf(1)) == -1) {
				return true;
			}
			Account userAccount = usersService.getUserAccount(specialUserId);
			Integer specialInviteId = userAccount.getUsers().getInviteId();
			// 邀请的主管或经理数量
			Integer inviteNum = userAccount.getInviteNum();
			// 如果是4位以上都记为5
			inviteNum = inviteNum > 4 ? 5 : inviteNum;

			Account account = new Account();
			account.setAccountId(userAccount.getAccountId());
			BigDecimal addScore = oneSpecialReward.multiply(BigDecimal.valueOf(inviteNum));
			if (addScore.compareTo(BigDecimal.valueOf(0)) == 1) {
				if (userAccount.getUsers().getUserType() == 0) {
					account.setFreezeScore(addScore);
					logScoreFreezeService.add(ScoreFreezeType.Special_awards.getCode(), specialFromId, specialUserId,
							orderNo + num, userAccount.getFreezeScore(), 1, addScore, remark);
				} else {
					account.setScore(addScore);
					account.setTotalScore(addScore);
					logScoreService.add(ScoreType.Special_awards.getCode(), specialFromId, specialUserId, orderNo + num,
							userAccount.getScore(), 1, addScore, remark);
				}
			}

			switch (inviteNum) {
			case 0:
				account.setOne(oneSpecialReward);
				account.setTwo(oneSpecialReward);
				account.setThree(oneSpecialReward);
				account.setFour(oneSpecialReward);
				account.setFive(oneSpecialReward);
				break;
			case 1:
				account.setTwo(oneSpecialReward);
				account.setThree(oneSpecialReward);
				account.setFour(oneSpecialReward);
				account.setFive(oneSpecialReward);
				break;
			case 2:
				account.setThree(oneSpecialReward);
				account.setFour(oneSpecialReward);
				account.setFive(oneSpecialReward);
				break;
			case 3:
				account.setFour(oneSpecialReward);
				account.setFive(oneSpecialReward);
				break;
			case 4:
				account.setFive(oneSpecialReward);
				break;
			default:
				break;
			}
			accountService.addFenrun(account);
			// 总获得特别奖励积分
			BigDecimal totalSpecial = totalSpecialReward.subtract(addScore);
			if (totalSpecial.compareTo(BigDecimal.valueOf(0)) == 1) {
				// 更新前的值暂记0
				logScoreSpecialService.add(ScoreSpecialType.Special_reward_add.getCode(), specialFromId, specialUserId,
						orderNo + num, BigDecimal.valueOf(0), 1, totalSpecial, "被邀请人消费特别奖励");
			}
			num++;
			if (num == 10) {
				return true;
			}
			this.addSpecialReward(specialUserId, specialInviteId, totalSpecialReward, num, orderNo, remark);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			try {
				logErrorService.add("doFenrunSpecialReward", specialUserId,
						"orderNo:" + orderNo + ",userId:" + specialUserId + ",addReward:" + totalSpecialReward,
						e.toString());
			} catch (Exception e1) {

			}
			return false;
		}
	}
}
